// main.c -- Defines the C-code kernel entry point, calls initialisation routines.
//           Made for JamesM's tutorials <www.jamesmolloy.co.uk>

#include "monitor.h"
#include "descriptor_tables.h"
#include "timer.h"
#include "paging.h"
#include "multiboot.h"
#include "fs.h"
#include "initrd.h"
#include "task.h"
#include "syscall.h"
#include "stdarg.h"
#include "string.h"
#include "x86.h"
#include "_printf.h"
#include "_krnl.h"
#include "i8259s.h"

void getvect(vector_t *v, unsigned vect_num);
void setvect(vector_t *v, unsigned vect_num);
void schedule(void);
void kprintf(const char *fmt, ...);

extern console_t _vc[];
void keyboard_irq(void);
void blink(void);
void putch(unsigned c);
void init_video(void);
void KeyboardIsr(void);

extern u32int placement_address;
u32int initial_esp;


int main(struct multiboot *mboot_ptr, u32int initial_stack)
{
    initial_esp = initial_stack;
    // Initialise all the ISRs and segmentation
    init_descriptor_tables();
    // Initialise the screen (by clearing it)
    monitor_clear();
    monitor_write("  ___               \n");
    monitor_write(" |    \\ /  \\    /   \n");
    monitor_write(" |__   |     \\/     \n");
    monitor_write("    |  |    /  \\    \n");
    monitor_write("  __|  |  /      \\  \n");
    // Initialise the PIT to 100Hz
    monitor_write("Initializing a 100Hz timer...\n");
    init_timer(50);

    // Find the location of our initial ramdisk.
    ASSERT(mboot_ptr->mods_count > 0);
    monitor_write("Mounting the initrd...\n");
    u32int initrd_location = *((u32int*)mboot_ptr->mods_addr);
    u32int initrd_end = *(u32int*)(mboot_ptr->mods_addr+4);
    // Don't trample our module with placement accesses, please!
    placement_address = initrd_end;
    // Initialise the initial ramdisk, and set it as the filesystem root.
    fs_root = initialise_initrd(initrd_location);

    // Start paging.
    monitor_write("Initializing paging...\n");
    initialise_paging();
    vector_t v;

    // Start multitasking.
    monitor_write("Initializing multi-tasking...\n");
    initialise_tasking();

    monitor_write("Starting video controller...\n");
    init_video();

    monitor_write("Testing keyboard...\n");
    init_keyboard();
    init_8259s();
    KeyboardIsr();
    enable();
   
    
    return 0;
}
